package com.shiyi.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.shiyi.common.Constants;
import com.shiyi.common.ResponseResult;
import com.shiyi.config.AliPayConfig;
import com.shiyi.dto.QrPayParam;
import com.shiyi.entity.PayLog;
import com.shiyi.entity.User;
import com.shiyi.entity.WebConfig;
import com.shiyi.mapper.PayMapper;
import com.shiyi.mapper.UserMapper;
import com.shiyi.service.ApiUserService;
import com.shiyi.service.WebConfigService;
import com.shiyi.vo.user.SystemUserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;

/**
 * @author niuben
 */
@RequestMapping("/v1/user")
@RestController
@Api(tags = "登录接口")
@RequiredArgsConstructor
public class AliPayController {

    private final PayMapper payMapper;

    private final UserMapper userMapper;

    private final ApiUserService userService;

    private final WebConfigService webConfigService;

    private final AliPayConfig aliPayConfig;
    @GetMapping("/generatePaymentLink")
    public ResponseResult pay(String amount) throws AlipayApiException {
        QrPayParam param = new QrPayParam();
        param.setSubject("卡尼奶积分充值");
        param.setTotal_amount(amount);
        WebConfig webConfig = webConfigService.getOne(new QueryWrapper<WebConfig>()
                .last(Constants.LIMIT_ONE));
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getServer_URL(),
                webConfig.getAppId(), webConfig.getPrivateKey(), aliPayConfig.getFORMAT(), aliPayConfig.getCHARSET(),
                webConfig.getPublicKey(), aliPayConfig.getSIGNTYPE());

        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        Object userId = StpUtil.getLoginIdDefaultNull();
        String userIdTemp = String.valueOf(System.currentTimeMillis()) + userId;
        String outTradeNoTail = userIdTemp.substring(userIdTemp.length()-4,userIdTemp.length());
        String outTradeNo = String.valueOf(System.currentTimeMillis()) + outTradeNoTail;//生成的流水号
        model.setOutTradeNo(outTradeNo);//设置商家这边的流水单号 后台写
        model.setSubject(param.getSubject());//设置商品名称
        model.setTotalAmount(param.getTotal_amount());//设置付款金额
        model.setBody("积分充值");//设置商品描述
        model.setTimeoutExpress(webConfig.getTimeout()+"m");//设置过期时间 格式：xxm 后台写
//        model.setProductCode(qrPayParam.getProduct_code());//设置产品码 - 二维码支付的话没有该功能

        request.setBizModel(model);//存入请求信息
        request.setNotifyUrl(webConfig.getNotifyUrl());//设置通知地址
        request.setReturnUrl(aliPayConfig.getReturn_url());//设置返回地址,二维码支付此功能无效

//        生成表单，二维码支付无表单
//        String form = alipayClient.pageExecute(request).getBody();

//        封装生成请求对象
        AlipayTradePrecreateResponse response = alipayClient.execute(request);

//        发送请求，获取返回信息
        System.out.println(response.getBody());

        HashMap<String, Object> map = new HashMap<>();

//        成功
        if (response.isSuccess()){
            System.out.println("调用成功");
            JSONObject responJson = JSONUtil.parseObj(response.getBody());
            JSONObject rsj = (JSONObject)responJson.get("alipay_trade_precreate_response");
            String qr_code = (String) rsj.get("qr_code");//获取二维码地址
            map.put("qrCode",qr_code);
            map.put("outTradeNo",outTradeNo);
            map.put("timeout",webConfig.getTimeout());

            //将待支付的交易记录保存
            PayLog payLog = new PayLog();
            payLog.setUserId(userId+"");
            payLog.setSubject("积分充值");
            payLog.setOutTradeNo(response.getOutTradeNo());
            payLog.setTotalAmount(amount);
            payLog.setTradeStatus("WAIT_BUYER_PAY");
            payLog.setTradeNo("");
            payLog.setBuyerLogonId("");
            payLog.setBuyerPayAmount("");
            payLog.setBody(response.getBody());
            payLog.setNotifyStatus("0");
            payLog.setNotifyResponse("");
            payMapper.savePay(payLog);
            return ResponseResult.success(map);
        }else {
            JSONObject responJson = JSONUtil.parseObj(response.getBody());
            JSONObject rsj = (JSONObject)responJson.get("alipay_trade_precreate_response");
            String res = (String) rsj.get("sub_msg");//获取返回错误的信息
            map.put("sub_msg",res);
            return ResponseResult.error(res);
        }
    }
    //    接收异步消息并同步订单状态
    @PostMapping("/alipaynotify")
    public String getnotify(String trade_no, String out_trade_no){
        PayLog payLog = payMapper.selectOne(Wrappers.<PayLog>lambdaQuery().eq(PayLog::getOutTradeNo, out_trade_no));
        payLog.setTradeStatus("1");
        payLog.setUpdateTime(new DateTime().toString());
        payLog.setTradeNo(trade_no);
        payLog.setTradeStatus("TRADE_SUCCESS");
        payLog.setOutTradeNo(out_trade_no);
        payMapper.updateById(payLog);
        SystemUserVO userVO = userMapper.getById(payLog.getUserId());
        //用户积分
        String userPoints = userVO.getPoints();
        BigDecimal totalAmount = new BigDecimal(payLog.getTotalAmount());
        BigDecimal userPointsAmount = new BigDecimal(userPoints);
        BigDecimal sum = totalAmount.add(userPointsAmount);
        userMapper.updateById(new User().setId(userVO.getId()).setPoints(sum.intValue()+""));
        return "success";
    }

    @RequestMapping(value = "queryPay",method = RequestMethod.GET)
    @ApiOperation(value = "查询是否支付成功", httpMethod = "GET", response = ResponseResult.class, notes = "查询是否支付成功")
    public ResponseResult queryPay(String outTradeNo){
        return userService.queryPay(outTradeNo);
    }
}

